home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-10 | 15.1 KB | 528 lines | [TEXT/CWIE] |
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Load PCI Driver Sample
- **
- ** by Matthew Xavier Mora, Apple Developer Technical Support
- **
- ** File: Load PCI DFriver.c
- **
- ** Copyright © 1996-1997 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
- */
-
- /*
- **
- ** This Code loads Wayne Flansburg PCI 'ndrv' so you can see it load without
- ** having to have a PCI card installed.
- ** This requires the PCI interfaces and libraries from ETO.
- **
- ** --------------------------------------
- ** Date Author Comments
- ** --------------------------------------
- ** 02-01-96 mxm I wrote the first version in the "Writing PCI drivers" class. Got it to load
- ** the sample driver I was writing. No real user interface
- ** to speak of.
- **
- ** 03-25-97 mxm Moved to a real app
- ** Fixed the can't load the library a second time bug.
- ** I was using HighestUnitNumber to get the unit number to load.
- ** I thought this call found the last used unit number. It
- ** actually expanded the unit table to the max number of
- ** entries! I put in MyFindSpaceInUnitTable routine and use it instead.
- ** Fix crashing Malph by moving it into an application shell. I don't
- ** know why it would cause Malph to crash.
- **
- ** 03-28-97 mxm Took out the MyFindSpaceInUnitTable routine. I wasn't using the
- ** InstallDriverFromFile correctly. HighestUnitNumber wasn't the problem.
- ** That's what I get for trying to program without the Documentation.
- ** Added Drag Manger and ODoOC support so you can drag a driver
- ** into the window or on the application and it will load it.
- ** Display more info from the driver.
- ** 04-15-97 mxm Cleaned it up for the Dev CD
- **
- ** 06-11-97 mxm Fixed the error -2538 by passing nil for the regID.
- **
- */
-
- //------------------------------------------------------------------
- #pragma mark Includes
- //------------------------------------------------------------------
-
- #include <Devices.h>
- #include <NameRegistry.h>
- #include <StandardFile.h>
- #include <LowMem.h>
- #include <Dialogs.h>
- #include "SimpleApp.h"
- #include <stdio.h>
- #include <string.h>
-
- //------------------------------------------------------------------
- #pragma mark Prototypes
- //------------------------------------------------------------------
-
- pascal OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath);
-
- //------------------------------------------------------------------
- #pragma mark Globals
- //------------------------------------------------------------------
-
- short gDrvrRefNum = 0; /* global variable for storing my driver reference number */
- long gLoadButton;
- long gUnloadButton;
- short gVert;
- short gLineHeight;
- NMRec gAlertNMRec;
- Str255 gAlertStr = "\pAn error occurred. Please bring Matt's PCI Loader to the front.";
- short gError = 0;
-
- //------------------------------------------------------------------
- #pragma mark Defines
- //------------------------------------------------------------------
-
- #define LMGetUnitTableEntryCount() (*((short *)0x1d2))
- #define LMSetUnitTableEntryCount(x) (*((short *)0x1d2) = (x))
-
- #pragma mark -
-
- //------------------------------------------------------------------
- static void AlertUser(short err)
- //------------------------------------------------------------------
- {
- // in this case just set the global and the idle routine will display the error
- gError = err;
- }
-
- /*
- // I grabbed this code from somewhere
- //------------------------------------------------------------------
- static short MyFindSpaceInUnitTable(void)
- //------------------------------------------------------------------
- {
- Ptr curUTableBase, newUTableBase;
- short curUTableEntries, newUTableEntries;
- short refNum, unitNum;
-
- // get current unit table values from low memory globals
- curUTableEntries = LMGetUnitTableEntryCount();
- curUTableBase = LMGetUTableBase();
-
- // search for empty space in the current unit table
- for ( unitNum = curUTableEntries - 1;
- unitNum >= 48; // lowest available unit number
- unitNum-- )
- {
- refNum = ~(unitNum);
- if (GetDCtlEntry(refNum) == nil)
- return(unitNum); // found a space
- }
-
-
- // no space in the current table, so make a new one
-
- // increase the size of the table by 16 (an arbitrary value)
- newUTableEntries = curUTableEntries + 16;
-
- // allocate space for the new table
- newUTableBase = NewPtrSysClear((long)newUTableEntries * sizeof(Handle));
- if (newUTableBase == nil) {
- return(MemError());
- }
- // copy the old table to the new table
- BlockMoveData(curUTableBase, newUTableBase, (long)curUTableEntries * sizeof(Handle));
-
- // set the new unit table values in low memory
- LMSetUTableBase(newUTableBase);
- LMSetUnitTableEntryCount( newUTableEntries);
-
- unitNum = newUTableEntries - 1;
-
- // unitNum = 0; //uh bad thing man.
- return(unitNum);
- }
-
- */
-
-
- //------------------------------------------------------------------
- static void ForceUpdate(void)
- //------------------------------------------------------------------
- {
- if (gSACurrentWindow) {
- SetPort(gSACurrentWindow);
- InvalRect(&gSACurrentWindow->portRect);
- }
- }
-
- //------------------------------------------------------------------
- static void UnloadDriver(void)
- //------------------------------------------------------------------
- {
- short err;
-
- if (gDrvrRefNum) {
- err = RemoveDriver(gDrvrRefNum, true);
- gDrvrRefNum = 0;
- }
- }
-
- //------------------------------------------------------------------
- static short InstallDriver(FSSpecPtr spec)
- //------------------------------------------------------------------
- {
- RegEntryID device={0,0};
- short lowUnitNumber,hiUnitNumber ;
- short err = -1;
-
-
- if (gDrvrRefNum) {
- UnloadDriver();
- }
- lowUnitNumber = 48 ; // MyFindSpaceInUnitTable();
- hiUnitNumber = HighestUnitNumber();
-
- if (lowUnitNumber > 0) {
-
- err = InstallDriverFromFile(spec,nil,lowUnitNumber ,hiUnitNumber,&gDrvrRefNum);
- if (err != noErr) {
- AlertUser(err); // we can be called from inside a drag handler so just set a flag
- SAEnableObject(gLoadButton);
- SADisableObject(gUnloadButton);
- } else {
- SAEnableObject(gUnloadButton);
- SADisableObject(gLoadButton);
- }
- }
- ForceUpdate();
- return err;
- }
-
- // Load a driver via StandardFile
- //------------------------------------------------------------------
- static short LoadDriver(void)
- //------------------------------------------------------------------
- {
-
- short err = -1;
-
- OSType typeList[4];
- OSType * typeListPtr = typeList;
- StandardFileReply reply;
-
-
- typeList[0] = 'ndrv';
-
- StandardGetFile(nil,1,typeList,&reply);
- if (reply.sfGood) {
- err = InstallDriver(&reply.sfFile);
- }
-
- return err;
- }
-
- // ODOC handler
- //------------------------------------------------------------------
- static pascal OSErr MyOpenFileProc(FSSpecPtr myFSSPtr)
- //------------------------------------------------------------------
- {
- short err;
-
- err = InstallDriver(myFSSPtr) ;
- return noErr;
- }
-
-
- //------------------------------------------------------------------
- static pascal short DoIdle(EventRecord *evt)
- //------------------------------------------------------------------
- {
- Str255 tempStr;
- short err;
- #pragma unused (evt)
- // in case we want to do something at idle time
-
- if (gError) {
- gAlertNMRec.qType = nmType;
- gAlertNMRec.nmFlags = 0;
- gAlertNMRec.nmPrivate = 0;
- gAlertNMRec.nmReserved = 0;
- gAlertNMRec.nmResp = nil;
- gAlertNMRec.nmStr = gAlertStr;
- gAlertNMRec.nmSound = nil;
- gAlertNMRec.nmMark = 1;
- gAlertNMRec.nmIcon = nil;
- err = AEInteractWithUser(kAEDefaultTimeout,&gAlertNMRec,nil);
-
- NumToString(gError,tempStr);
- ParamText(tempStr,"\p","\p","\p");
- Alert(1002,nil);
- gError = 0;
- }
- return noErr;
- }
-
- //------------------------------------------------------------------
- static pascal short DoLoadDriver(ButtonItemRef me,long refCon)
- //------------------------------------------------------------------
- {
- #pragma unused (me,refCon)
- short err;
-
- err = LoadDriver();
- if (err == noErr ) {
- SADisableMe();
- SAEnableObject(gUnloadButton);
- ForceUpdate();
- }
- return noErr;
- }
-
- //------------------------------------------------------------------
- static pascal short DoUnloadDriver(ButtonItemRef me,long refCon)
- //------------------------------------------------------------------
- {
- #pragma unused (me,refCon)
-
- UnloadDriver();
- SADisableMe();
- SAEnableObject(gLoadButton);
- ForceUpdate();
-
- return noErr;
- }
-
- //------------------------------------------------------------------
- static GetLineHeight(void)
- //------------------------------------------------------------------
- {
- FontInfo info;
-
- GetFontInfo(&info);
- return (info.ascent + info.descent + info.leading);
- }
-
- //------------------------------------------------------------------
- static void DrawItem(StringPtr label,StringPtr text)
- //------------------------------------------------------------------
- {
- DrawString (label);
- DrawString (text);
- MoveTo(5,gVert);
- gVert += gLineHeight;
- }
-
- //------------------------------------------------------------------
- static void DrawHex(StringPtr label,long n)
- //------------------------------------------------------------------
- {
- char s[256];
-
- sprintf(s,"%0X",n);
- DrawString (label);
- DrawText(s,0,strlen(s));
- MoveTo(5,gVert);
- gVert += gLineHeight;
- }
-
- //------------------------------------------------------------------
- static void DrawHandle(StringPtr label,Handle text)
- //------------------------------------------------------------------
- {
- DrawString (label);
- if (text) {
- DrawText (*text,0,GetHandleSize(text));
- }
- MoveTo(5,gVert);
- gVert += gLineHeight;
- }
-
- //------------------------------------------------------------------
- static void DrawNumber(StringPtr label,long n)
- //------------------------------------------------------------------
- {
- Str255 tempStr;
-
- NumToString(n,tempStr);
- DrawString (label);
- DrawString (tempStr);
- MoveTo(5,gVert);
- gVert += gLineHeight;
- }
-
- //------------------------------------------------------------------
- static pascal short MyUpdate(long refCon)
- //------------------------------------------------------------------
- {
- #pragma unused (refCon)
- Str255 tempStr;
- UnitNumber unitNum;
- DriverFlags flags;
- DriverOpenCount count;
- RegEntryID device;
- CFragHFSLocator driverLoadLocation;
- CFragConnectionID fragmentConnID;
- DriverEntryPointPtr fragmentMain;
- DriverDescription driverDesc;
- FSSpec fileSpec;
- Handle fullPath = nil;
- short err = 0;
- short fullPathLength;
-
- gLineHeight = GetLineHeight();
-
- gVert = 120;
- MoveTo(5,gVert);
- gVert += gLineHeight;
-
- if (gDrvrRefNum) {
-
- DrawString("\pThe driver is loaded. refNum = (");
- NumToString(gDrvrRefNum,tempStr);
- DrawString (tempStr);
- DrawString("\p)");
- MoveTo(5,gVert);
-
- gVert += gLineHeight;
- driverLoadLocation.u.onDisk.fileSpec = &fileSpec;
- err = GetDriverInformation(gDrvrRefNum,
- &unitNum,
- &flags,
- &count,
- tempStr,
- &device,
- &driverLoadLocation,
- &fragmentConnID,
- &fragmentMain,
- &driverDesc);
-
- DrawItem("\pName: ",tempStr);
- DrawNumber("\pUnitNumber: ",unitNum);
- DrawNumber("\pCount: ",count);
- DrawHex("\pflags: ",flags);
-
- err = FSpGetFullPath(&fileSpec,&fullPathLength, &fullPath);
- if (fullPath) {
- DrawHandle("\pPath: ",fullPath);
- DisposeHandle(fullPath);
- }
- DrawHex("\pFragment Main: 0x",(long)fragmentMain);
- } else {
- DrawString("\pNo Driver Loaded. ");
- }
-
- return noErr;
- }
-
- //---------------------------------------------------------------------------------------
- static pascal OSErr MyPutData (ObjectItemRef orh,OSType kind,Ptr data,long len,long flags)
- //---------------------------------------------------------------------------------------
- {
- #pragma unused (orh,len,flags)
-
- HFSFlavor * theFile;
-
- if (kind == flavorTypeHFS) {
- theFile = (HFSFlavor *)data;
-
- if (theFile->fileType == 'cfrg' ) {
- InstallDriver(&theFile->fileSpec);
- }
- }
-
-
- return noErr;
- }
-
-
- // The drag receive handler
- //------------------------------------------------------------------
- static pascal short MyReceive(ObjectItemRef orh,DragReference theDrag)
- //------------------------------------------------------------------
- {
- #pragma unused(orh)
- ItemReference itemRef;
- Size dataSize;
- HFSFlavor theHFSFlavor;
- OSErr retCode;
-
-
- // There is only one item, so get its reference number.
- retCode = GetDragItemReferenceNumber(theDrag, 1, &itemRef);
-
- if (retCode == noErr) {
- dataSize = sizeof(HFSFlavor);
- retCode = GetFlavorData(theDrag, itemRef, flavorTypeHFS, &theHFSFlavor, &dataSize, 0);
- if (retCode == noErr) {
- InstallDriver(&theHFSFlavor.fileSpec) ;
- }
-
- }
- return retCode;
- }
-
- //------------------------------------------------------------------
- void main(void)
- //------------------------------------------------------------------
- {
- long buttonID = 1;
- long textID = 2;
- long dragID = 3;
- Str255 tempStr;
- Rect r ;
- long gMyWindowID;
- short err;
-
- InitSimpleApp(2,kUseStandardMenu); // Simple App Sets up the Tool Box For us
- gMyWindowID = GetDocumentWindow (128); // Get our stored window
- SetOpenFileProc (MyOpenFileProc); // set open file proc. This is called on an ODOC event
-
- SetWTitle(gSACurrentWindow,"\pMatt's PCI Driver Loader");
-
- InstallIdleProc(DoIdle);
- SetWindowUpdateProc(gSACurrentWindow,MyUpdate ); //gSACurrentWindow for now, its a Kludge
- GetIndString(tempStr,kStaticStrings,kButtonName); // Get button name
-
- SetRectDimensions(&r, 180, 20); // This Sets its size without changing it position
- SetRectLocation(&r, 10, 30); // This Sets a rects anchor point
- (void)InstallPushButton(&buttonID,gSACurrentWindow,tempStr,&r,0,DoLoadDriver,nil);
- gLoadButton = buttonID;
- OffsetRect(&r,200,0);
- GetIndString(tempStr,kStaticStrings,3); // Get button name
- (void)InstallPushButton(&buttonID,gSACurrentWindow,tempStr,&r,0,DoUnloadDriver,nil);
- gUnloadButton = buttonID;
- SADisableMe();
-
-
- SetRect(&r,4,55,gSACurrentWindow->portRect.right - 4,110);
- GetIndString(tempStr,kStaticStrings,kAboutText); // Get about this snippet text
- (void)InstallStaticText(&textID,gSACurrentWindow,tempStr,&r);
-
- // lets add drag and drop support for our window
- err = InstallDragObject(&dragID,gSACurrentWindow,"\p",&gSACurrentWindow->portRect, nil, nil, MyReceive, 0);
- err = SAInstallStandardDragHandlers(gSACurrentWindow); // enable dragging
- err = SAAddWindowDragDataTypes(gSACurrentWindow,flavorTypeHFS); // we accept flavorTypeHFS
-
- Run(); //Let SimpleApp handle the rest
-
- // lets check and see if the driver is still loaded and ask the
- // user what to do if it is loaded
- if (gDrvrRefNum) {
- short itemHit;
-
- itemHit = Alert(1001,nil);
- if (itemHit == 1 ) {
- UnloadDriver();
- }
- }
- }
-
-